import Vapor

struct ReferenceController: RouteCollection {
    
    func boot(routes: RoutesBuilder) throws {
        let projectRoute = routes.grouped("api", "reference")
        projectRoute.post(use: createHandler)
        projectRoute.put(use: updateHandler)
        projectRoute.delete(":id", use: deleteHandler)

        projectRoute.get(use: getAllHandler)
        projectRoute.get(":referenceID", use: getHandler)
        projectRoute.get(":referenceID", "texts", use: getTextsHandler)
        projectRoute.get(":referenceID", "videos", use: getVideosHandler)
        projectRoute.get(":referenceID", "images", use: getImagesHandler)
        
        
    }
    
    func createHandler(_ req: Request) throws -> EventLoopFuture<Reference> {
        let reference = try req.content.decode(Reference.self)
        return reference.save(on: req.db).map { reference }
    }
    
    func updateHandler(_ req: Request) throws -> EventLoopFuture<Reference> {
        let data = try req.content.decode(Reference.self)
        return Reference.find(data.id, on: req.db).unwrap(or: Abort(.notFound)).flatMap {reference in
            reference.referenceTitle = data.referenceTitle
            reference.rbm = data.rbm
            reference.countryIso = data.countryIso
            reference.projectNumbers = data.projectNumbers
            reference.latitude = data.latitude
            reference.longitude = data.longitude
            reference.coordinateIsExact = data.coordinateIsExact
            reference.hasImages = data.hasImages
            reference.hasVideos = data.hasVideos
            reference.isBreederSystems = data.isBreederSystems
            reference.isBroilerSystems = data.isBroilerSystems
            reference.isCageFreeSystems = data.isCageFreeSystems
            reference.isConventionalLayerSystems = data.isConventionalLayerSystems
            reference.isEnrichedCages = data.isEnrichedCages
            reference.isManureHandling = data.isManureHandling
            reference.mainImageFileOcId = data.mainImageFileOcId
            reference.mainTestimonialImageFileOcId = data.mainTestimonialImageFileOcId
            return reference.save(on: req.db).map { return reference }
            
        }
    }
    
    func deleteHandler(_ req: Request)
      throws -> EventLoopFuture<HTTPStatus> {
        Reference.find(req.parameters.get("id"), on: req.db)
        .unwrap(or: Abort(.notFound))
        .flatMap { reference in

            reference.delete(on: req.db)
            .transform(to: .noContent)
      }
    }
    
    func getAllHandler(_ req: Request) throws -> EventLoopFuture<[Reference]> {
        Reference.query(on: req.db).all()
    }
    
    func getHandler(_ req: Request) throws -> EventLoopFuture<Reference> {
        Reference.find(req.parameters.get("referenceID"), on: req.db).unwrap(or: Abort(.notFound))
    }
    
    func getTextsHandler(_ req: Request) throws -> EventLoopFuture<[ReferenceText]> {
        Reference.find(req.parameters.get("referenceID"), on: req.db).unwrap(or: Abort(.notFound)).flatMap { reference in
            reference.$texts.get(on: req.db)
        }
    }
    
    func getImagesHandler(_ req: Request) throws -> EventLoopFuture<[ReferenceImage]> {
        Reference.find(req.parameters.get("referenceID"), on: req.db).unwrap(or: Abort(.notFound)).flatMap { reference in
            reference.$images.get(on: req.db)
        }
    }
    
    func getVideosHandler(_ req: Request) throws -> EventLoopFuture<[ReferenceVideo]> {
        Reference.find(req.parameters.get("referenceID"), on: req.db).unwrap(or: Abort(.notFound)).flatMap { reference in
            reference.$referenceVideos.get(on: req.db)
        }
    }
}
